home *** CD-ROM | disk | FTP | other *** search
- ******************************************************************************
- * Program Name: soundx.prg
- * Coded by: Richard R. Schafer
- *
- * Produces a code based on the "Soundex" method originally developed
- * by M.K. Odell and R.C. Russell. Algorithm can be found on page
- * 392 of Knuths' book 'Sorting and Searching', volume 3 of 'The Art
- * of Computer Programming", Addison/Wesley publisher.
- *
- * All non alphabetic characters and numbers are discarded. Converts input
- * character string to uppercase and then procedes.
- *
- * usage: soundxx(gp_name)
- *
- * gp_name = input character string on which soundex code is developed
- *
- ******************* RELEASED INTO THE PUBLIC DOMAIN **************************
-
- FUNCTION soundxx
-
- parameters gp_name
-
- private pv_name_, pv_next, pv_code, pv_newname,pv_winscrn,pv_colorset
- private pv_array,pv_arrayct,NULL
-
- * this would probably be a global variable under normal usage
- NULL = ""
-
- * Set up way to get out if we didn't get any parameters,
- * as well as give the programmer a way to determine if
- * things went well
- begin sequence
- * did we get any parameters?
- if pcount() < 1
- set cursor off
-
- * save the screen window
- pv_winscrn = savescreen(08,10,13,69)
-
- * save the current screen attribs
- pv_colorset = setcolor()
- set color to "n/w,w+/n"
-
- * draw a box around the window
- @08,10 clear to 13,69
- @08,10 to 13,69 double
-
- * wait for user response
- @09,12 say "Usage: soundxx(X_name)"
- @10,12 say "Where X_name is your variable containing the name"
- @11,12 say "you want a soundex code for"
- @12,12 say "PRESS ANY KEY TO CONTINUE"
- inkey(0)
- set cursor on
-
- * reset screen attribs
- set color to &pv_colorset
-
- * restore the screen
- restscreen(08,10,13,69,pv_winscrn)
-
- * return to calling function
- pv_code = .f.
-
- * and then break out of the sequence and return
- break
- endif
-
- * make sure everything is caps
- pv_newname = upper(gp_name)
-
- * set to the # char in the input character string
- pv_arrayct = len(rtrim(pv_newname))
-
- * declare an array
- declare pv_name_[pv_arrayct]
-
- * initialize a counter
- pv_array = 1
-
- * now we'll prepare the name string
- for pv_count = 1 to pv_arrayct
-
- * we'll eliminate everything that
- * isn't an uppercase alpha character
- if asc(substr(pv_newname,pv_count,1)) < asc("A") .or.;
- asc(substr(pv_newname,pv_count,1)) > asc("Z")
- else
-
- * put it into our array
- * increment the array counter
- pv_name_[pv_array] = substr(pv_newname,pv_count,1)
- pv_array = pv_array + 1
- endif
-
- next
-
- * initialize the code holder
- pv_code = NULL
-
- * set to length of array
- pv_arrayct = len(pv_name_)
-
- * reset array counter
- pv_array = 1
-
- * put the 1st char into the code
- * as is (not a number here)
- pv_code = pv_code + pv_name_[pv_array]
-
- * We'll stay in the loop
- * until we fill the name string
- * or until we hit the end of the array
- do while (len(pv_code)) < 4 .and. (pv_array < pv_arrayct)
-
- * increment array counter
- pv_array = pv_array + 1
-
- do case
-
- * we skip these characters
- case pv_name_[pv_array] $ "AEHIOUWY"
-
- * and get numbers for the rest
- case pv_name_[pv_array] $ "BFPV"
- pv_code = pv_code + "1"
- case pv_name_[pv_array] $ "CGJKQSXZ"
- pv_code = pv_code + "2"
- case pv_name_[pv_array] $ "DT"
- pv_code = pv_code + "3"
- case pv_name_[pv_array] $ "L"
- pv_code = pv_code + "4"
- case pv_name_[pv_array] $ "MN"
- pv_code = pv_code + "5"
- case pv_name_[pv_array] $ "R"
- pv_code = pv_code + "6"
- endcase
-
- * if we haven't gone beyond the end of the array
- if (pv_array + 1) < pv_arrayct
-
- * is the next character the same
- * if it is, we'll skip it and
- * use the following character
- if pv_name_[pv_array] == pv_name_[pv_array + 1]
- pv_array = pv_array + 1
- endif
-
- endif
-
- enddo
-
- * if the code isn't 4 characters long
- * pad it with zeroes
- if len(pv_code) < 4
- pv_code = pv_code + replicate("0",4 - (len(pv_code)))
- endif
- end sequence
- return(pv_code)